package com.xbongbong.paas.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.appmodule.pojo.dto.AppModuleDetailDTO;
import com.xbongbong.pro.appmodule.pojo.dto.AppModuleListDTO;
import com.xbongbong.pro.appmodule.pojo.dto.AppModuleOpenDTO;
import com.xbongbong.pro.appmodule.pojo.dto.AppModuleSaveDTO;
import com.xbongbong.pro.appmodule.pojo.dto.SendSMSDTO;
import com.xbongbong.pro.appmodule.pojo.vo.AppModuleDetailVO;
import com.xbongbong.pro.appmodule.pojo.vo.AppModuleHotVO;
import com.xbongbong.pro.appmodule.pojo.vo.AppModuleListVO;
import com.xbongbong.pro.appmodule.pojo.vo.AppModuleOpenVO;
import com.xbongbong.pro.appmodule.pojo.vo.AppModuleSaveVO;
import com.xbongbong.pro.appmodule.pojo.vo.AppRemindVO;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.esign.pojo.dto.EsignAuthUrlDTO;
import com.xbongbong.pro.esign.pojo.vo.EsignAuthUrlVO;
import com.xbongbong.pro.esign.pojo.vo.EsignCorpStatusVO;
import com.xbongbong.saas.service.AppModuleService;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Objects;

/**
 * @description: 模板中心
 * @Author: hongxiao
 * @date: 2019-03-02 15:43
 * @since v1.0
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/appModule")
public class AppModuleController {

    @Resource
    private AppModuleService appModuleService;
    @Resource
    private PaasRedisHelper paasRedisHelper;

    /**
     * 模板中心：列表
     * @param listDTO 入参
     * @param br
     * @return
     * @throws
     *
     * @author hongxiao
     * @date: 2019-03-02 17:13
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String list(@RequestBody @Valid AppModuleListDTO listDTO, BindingResult br) {
        XbbResponse<AppModuleListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                AppModuleListVO listVO = appModuleService.list(listDTO);
                response = new XbbResponse<>(listVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 应用搜索
     * @param listDTO
     * @param br
     * @return java.lang.String
     * @author 石安
     * @date 2020-02-19
     */
    @RequestMapping(value = "/search", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String search(@RequestBody @Valid AppModuleListDTO listDTO, BindingResult br) {
        XbbResponse<AppModuleListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                AppModuleListVO listVO = appModuleService.search(listDTO);
                response = new XbbResponse<>(listVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 模板中心：详情
     * @param detailDTO 入参
     * @param br
     * @return
     * @throws
     *
     * @author hongxiao
     * @date: 2019-03-02 17:17
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/detail", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String detail(@RequestBody @Valid AppModuleDetailDTO detailDTO, BindingResult br) {
        XbbResponse<AppModuleDetailVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                AppModuleDetailVO detailVO = appModuleService.detail(detailDTO);
                response = new XbbResponse<>(detailVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 模板中心：应用的第一次开启（开通应用）
     * @param openDTO 入参
     * @param br
     * @return
     * @throws
     *
     * @author hongxiao
     * @date: 2019-03-02 17:18
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/open", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String open(@RequestBody @Valid AppModuleOpenDTO openDTO, BindingResult br) {
        XbbResponse<AppModuleOpenVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            // ----------------------------------repeat post----------------------------------------------
            // 判断是否跳过重复提交校验
            if (!Boolean.TRUE.equals(openDTO.getIgnoreConCheck())) {
                //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(openDTO)) {
                    response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                    return JSON.toJSONString(response);
                }
            }
            // ----------------------------------repeat post----------------------------------------------
            try {
                AppModuleOpenVO openVO = appModuleService.open(openDTO);
                response = new XbbResponse<>(openVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            } catch (Exception e) {
                response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100001);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 开通应用获取需开通的套餐信息
     * @param appModuleOpenDTO
     * @param br
     * @return java.lang.String
     * @author 石安
     * @date 2019-12-27
     */
    @RequestMapping(value = "/app/getOpen", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String appOpenDetail(@RequestBody @Valid AppModuleOpenDTO appModuleOpenDTO, BindingResult br) {
        XbbResponse<AppModuleOpenVO> response;
        AppModuleOpenVO appModuleOpenVO;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                appModuleOpenVO = appModuleService.appOpenDetail(appModuleOpenDTO);
                response = new XbbResponse<>(appModuleOpenVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 开通应用
     * @param appModuleSaveDTO
     * @param br
     * @return java.lang.String
     * @author 石安
     * @date 2019-12-27
     */
    @RequestMapping(value = "/app/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String addMeal(@RequestBody @Valid AppModuleSaveDTO appModuleSaveDTO, BindingResult br) {
        XbbResponse<AppModuleSaveVO> response;
        AppModuleSaveVO appModuleSaveVO;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(appModuleSaveDTO.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(appModuleSaveDTO)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                appModuleSaveVO = appModuleService.addMeal(appModuleSaveDTO);
                response = new XbbResponse<>(appModuleSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     *  发送短信
     * @param sendSMSDTO
     * @param br
     * @return java.lang.String
     * @author 石安
     * @date 2019-08-13
     */
    @RequestMapping(value = "/mobileCode/sendSMS", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String sendSMS(@RequestBody @Valid SendSMSDTO sendSMSDTO, BindingResult br){
        XbbResponse<AppModuleSaveVO> response;
        AppModuleSaveVO appModuleSaveVO;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                appModuleSaveVO = appModuleService.sendSMS(sendSMSDTO);
                response = new XbbResponse<>(appModuleSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 申请应用试用或开通
     * @param saveDTO
     * @param br
     * @return java.lang.String
     * @author 石安
     * @date 2020-01-09
     */
    @RequestMapping(value = "/applyApp", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String applyApp(@RequestBody @Valid AppModuleSaveDTO saveDTO, BindingResult br){
        XbbResponse<AppModuleSaveVO> response;
        AppModuleSaveVO appModuleSaveVO;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(saveDTO.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(saveDTO)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                appModuleSaveVO = appModuleService.applyApp(saveDTO);
                response = new XbbResponse<>(appModuleSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 应用到期提醒
     * @param baseDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/expire/remind", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String remindExpire(@RequestBody @Valid BaseDTO baseDTO, BindingResult br){
        XbbResponse<AppRemindVO> response;
        AppRemindVO appRemindVO;
        if (br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                appRemindVO = appModuleService.remindExpire(baseDTO);
                response = new XbbResponse<>(appRemindVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 模板中心：未开通的热门应用
     * @param hotDTO 入参
     * @param br
     * @return
     * @throws
     *
     * @author hongxiao
     * @date: 2019-03-02 17:19
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/hot", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String hot(@RequestBody @Valid BaseDTO hotDTO, BindingResult br) {
        XbbResponse<AppModuleHotVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                AppModuleHotVO hotVO = appModuleService.hot(hotDTO);
                response = new XbbResponse<>(hotVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取公司状态(e签宝)
     * @param baseDTO
     * @param br
     * @return
     * 创建时间 2020/6/16 2:50 PM
     * 修改时间 2020/6/16 2:50 PM
     * @author chy
     */
    @RequestMapping(value = "/getCorpStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCorpStatus(@RequestBody @Valid BaseDTO baseDTO, BindingResult br) {
        XbbResponse<EsignCorpStatusVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                EsignCorpStatusVO esignCorpStatusVO = appModuleService.getEsignCorpStatus(baseDTO);
                response = new XbbResponse<>(esignCorpStatusVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取授权地址(e签宝)
     * @param esignAuthUrlDTO
     * @param br
     * @return
     * 创建时间 2020/6/16 2:50 PM
     * 修改时间 2020/6/16 2:50 PM
     * @author chy
     */
    @RequestMapping(value = "/getAuthUrl", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getAuthUrl(@RequestBody @Valid EsignAuthUrlDTO esignAuthUrlDTO, BindingResult br) {
        XbbResponse<EsignAuthUrlVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                EsignAuthUrlVO esignAuthUrlVO = appModuleService.getEsignAuthUrl(esignAuthUrlDTO);
                response = new XbbResponse<>(esignAuthUrlVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }
}
